package nc.impl.hrpbm.budgetmake.budgetmake;

import java.util.Map;
import java.util.Queue;
import java.util.stream.Collectors;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.framework.common.InvocationInfoProxy;
import nc.bs.hrpbm.budgetmake.ProjectBudgetMakedetailService;
import nc.jdbc.framework.processor.MapListProcessor;
import nc.jdbc.framework.processor.MapProcessor;
import nc.pub.hrpbm.util.HrpbmReportUtils;
import nc.pub.smart.context.SmartContext;
import nc.pub.smart.data.DataSet;

import nc.vo.pub.BusinessException;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nccloud.commons.lang.ArrayUtils;
import nc.pub.smart.data.DataSet;
import nc.pub.smart.metadata.Field;
import nc.pub.smart.metadata.MetaData;
import nc.vo.pub.BusinessException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

public class ProjectBudgetMakedetailServiceImpl implements ProjectBudgetMakedetailService{
	private final String cwbudgetdeptcode="405";
	public BaseDAO getBaseDAO() {
		return baseDAO == null ? new BaseDAO() : baseDAO;
	}
	private BaseDAO baseDAO;
	HrpbmReportUtils Utils = new HrpbmReportUtils();
	String[] fields = new String[] {"amount_firstup", "inoutbusiclassname",
			"pk_budgetdept","deptname","pk_projectclass","classlevel",
			"type_name","pk_updept","pk_fundsource",
			"billno","pk_budgetmake","pk_project","inoutbusiclasscode",
			"f1project_name","f2project_name","f3project_name",

			"amount_oneup","amount_onedown","amount_twoup","amount_twodown",
			"oneup_01","onedown_01","twoup_01","twodown_01",
			"oneup_02","onedown_02","twoup_02","twodown_02",
			"oneup_03","onedown_03","twoup_03","twodown_03",
			"oneup_04","onedown_04","twoup_04","twodown_04",
			"oneup_05","onedown_05","twoup_05","twodown_05"};
	String[] fieldTypes =new String[] {"String","String","String","String",
			"String","String","String","String",
			"String","String","String","String",
			"String","String","String","String",
			"Double","Double" ,"Double",
			"Double" ,"Double" ,"Double" ,"Double" ,
			"Double" ,"Double" ,"Double" ,"Double" ,
			"Double" ,"Double" ,"Double" ,"Double" ,
			"Double" ,"Double" ,"Double" ,"Double" ,
			"Double" ,"Double" ,"Double" ,"Double" ,"Double"};
	@SuppressWarnings("unchecked")
	@Override
	public  DataSet process(SmartContext context) throws BusinessException {


		//获取查询条件

		HrpbmReportUtils.handelContext(context);




		//初始化元数据
		MetaData meta = getMetaData(fieldTypes, fields);



		List businessData =getBusinessData(context);

		return buildDataSetobj(meta, businessData, fields);


	}
	private List getBusinessData(SmartContext context) throws BusinessException {

		String pk_org = (String) context.getAttribute("pk_org");
		// 1001A210000000000R5B,1001A210000000000R5G
		String budgetdept = (String) context.getAttribute("pk_budgetdept");
		String inoutlevel = (String) context.getAttribute("level");
		String pk_inoutclass = (String) context.getAttribute("pk_inoutclass");
		String nyear = (String) context.getAttribute("nyear");
		String isfund = (String) context.getAttribute("isfund");
		String f1project = (String) context.getAttribute("f1project");
		String f2project = (String) context.getAttribute("f2project");
		String f3project = (String) context.getAttribute("f3project");

		String sql = "SELECT DISTINCT inoutbusiclass.code                  inoutbusiclasscode,\n" +
				"                inoutbusiclass.name                  inoutbusiclassname,\n" +
				"                inoutbusiclass.pk_parent             inoutbusiclassparent,\n" +
				"                detail.pk_inoutclass                 pk_inoutclass,\n" +
				"                make.pk_budgetdept                   pk_budgetdept,\n" +
				"                budgetdept.name                      deptname,\n" +
				"                projectclass.eps_name                type_name,\n" +
				"                make.pk_updept                       pk_updept,\n" +
				"                detail.pk_fundsource                 pk_fundsource,\n" +
				"                fundsource.code                      sourcecode,\n" +
				"                make.billno                          billno,\n" +
				"                detail.pk_project                    pk_project,\n" +
				"                detail.budgetno,\n" +
				"                CASE\n" +
				"                    WHEN project.def1 = '1' THEN project.project_name\n" +
				"                    WHEN f2project.def1 = '1' THEN f2project.project_name\n" +
				"                    WHEN f3project.def1 = '1' THEN f3project.project_name\n" +
				"                    ELSE null\n" +
				"                    END AS                           f1project_name,\n" +
				"\n" +
				"                CASE\n" +
				"                    WHEN project.def1 = '2' THEN project.project_name\n" +
				"                    WHEN f2project.def1 = '2' THEN f2project.project_name\n" +
				"                    WHEN f3project.def1 = '2' THEN f3project.project_name\n" +
				"                    ELSE null\n" +
				"                    END AS                           f2project_name,\n" +
				"                CASE\n" +
				"                    WHEN project.def1 = '3' THEN project.project_name\n" +
				"                    WHEN f2project.def1 = '3' THEN project.project_name\n" +
				"                    WHEN f3project.def1 = '3' THEN project.project_name\n" +
				"                    ELSE null\n" +
				"                    END AS                           f3project_name,\n" +
				"                CASE\n" +
				"                    WHEN project.def1 = '1' THEN project.pk_project\n" +
				"                    WHEN f2project.def1 = '1' THEN f2project.pk_project\n" +
				"                    WHEN f3project.def1 = '1' THEN f3project.pk_project\n" +
				"                    ELSE null\n" +
				"                    END AS                           pk_f1project,\n" +
				"\n" +
				"                CASE\n" +
				"                    WHEN project.def1 = '2' THEN project.pk_project\n" +
				"                    WHEN f2project.def1 = '2' THEN f2project.pk_project\n" +
				"                    WHEN f3project.def1 = '2' THEN f3project.pk_project\n" +
				"                    ELSE null\n" +
				"                    END AS                           pk_f2project,\n" +
				"                CASE\n" +
				"                    WHEN project.def1 = '3' THEN project.pk_project\n" +
				"                    WHEN f2project.def1 = '3' THEN project.pk_project\n" +
				"                    WHEN f3project.def1 = '3' THEN project.pk_project\n" +
				"                    ELSE null\n" +
				"                    END AS                           pk_f3project,\n" +
				"                make.totalamount                     totalamount,\n" +
				"                case\n" +
				"                    when make.approvestatus = '1' then detail.amount_firstup\n" +
				"                    else make1.amount_firstup end           amount_firstup,\n" +
				"                case\n" +
				"                    when make.approvestatus = '1' then detail.amount_firstdown\n" +
				"                    else make1.amount_firstdown end           amount_firstdown,\n" +
				"                case\n" +
				"                    when make.approvestatus = '1' then detail.amount_seconddown\n" +
				"                    else make1.amount_seconddown end           amount_seconddown,\n" +
				"                case\n" +
				"                    when make.approvestatus = '1' then detail.amount_secondup\n" +
				"                    else make1.amount_secondup end           amount_secondup,\n" +
				"                inoutbusiclass.def1                  classlevel\n" +
				"FROM hrpbm_budgetreplydetail detail\n" +
				"         LEFT JOIN hrpbm_budgetreply make\n" +
				"                   ON make.pk_budgetreply = detail.pk_budgetreply\n" +
				"         left join hrpbm_budgetmakedetail make1\n" +
				"                   on make1.budgetno = detail.budgetno\n" +
				"         LEFT JOIN hrpbm_budgetdept budgetdept\n" +
				"                   ON budgetdept.pk_budgetdept = make.pk_budgetdept\n" +
				"         LEFT JOIN bd_project project\n" +
				"                   ON detail.pk_project = project.pk_project\n" +
				"         LEFT JOIN pm_eps projectclass\n" +
				"                   ON project.pk_eps = projectclass.pk_eps\n" +
				"         LEFT JOIN bd_project f2project\n" +
				"                   ON f2project.pk_project = project.pk_parentpro\n" +
				"         LEFT JOIN bd_project f3project\n" +
				"                   ON f3project.pk_project = f2project.pk_parentpro\n" +
				"         LEFT JOIN bd_inoutbusiclass inoutbusiclass\n" +
				"                   ON inoutbusiclass.pk_inoutbusiclass = detail.pk_inoutclass\n" +
				"         LEFT JOIN bd_fundsource fundsource\n" +
				"                   ON fundsource.pk_fundsource = detail.pk_fundsource\n" +
				"         LEFT JOIN\n" +
				"     (SELECT factorvalue3, factorvalue2, factorvalue5\n" +
				"      FROM fip_docview_b viewb\n" +
				"               LEFT JOIN\n" +
				"           fip_docview fview on viewb.pk_classview = fview.pk_classview\n" +
				"      WHERE fview.viewcode = 'YS001') docview ON docview.factorvalue5 = detail.pk_inoutclass\n" +
				"         LEFT JOIN\n" +
				"     bd_defdoc doc2 ON doc2.pk_defdoc = docview.factorvalue3\r\n" +
				" WHERE (make.pk_org = '"+pk_org+"'\r\n" +
				"        AND make.nyear = '"+nyear+"' )\r\n" +
				"        AND ( make.transtype = 'BM25-Cxx-CD-YS03' and make.taskstate = 13) ";

		if(pk_inoutclass!=null) {
			String[] sps = pk_inoutclass.toString().split(",");
			String join = StringUtils.join(sps, ",");
			sql += " and detail.pk_inoutclass = '"+pk_inoutclass+"'";
		}
		if(getpkbudgetdept(budgetdept) != null) {
			sql += " and make.pk_budgetdept in (" + getpkbudgetdept(budgetdept) + ") ";
		}
		if(isfund!=null) {
			sql += " and doc2.code = '"+isfund+"'";

		}
		if(f1project!=null) {

		}


		// 如果还有错误 那一定是left reply表的时候使用的max 但我实在想不到如何去重查询了
		// 折磨了我几天这个取数逻辑 这玩意还没法去找个地方核对 头疼
		List<Map<String,Object>> list = (ArrayList<Map<String,Object>>)getBaseDAO().executeQuery(sql, new MapListProcessor());
		initFundsource(list);
		List<Map<String,Object>> newList = new ArrayList();
		//initFundsource(list);
		List<Map<String,Object>> listToCopyInto = new ArrayList<>();
//		Collections.copy( list,listToCopyInto);
//		Collections.copyList(list,listToCopyInto);
		listToCopyInto = ObjectUtils.clone(list);

		List<Map<String,Object>> list2 = initList(list,newList);



		List list1 = initnewList(list2);
		//List<Map<String,Object>> List2= initnewList(list1);



		listToCopyInto.addAll(list1);



		listToCopyInto.sort(Comparator.comparing(map -> (String) map.get("inoutbusiclasscode")));
		//	assignLevels(listToCopyInto);

		List<Map<String, Object>> originalList = new ArrayList<>();

//		if(f1project!=null||f1project!=null||f1project!=null) {
		if(true) {

			for (Map<String, Object> listmap : listToCopyInto) {
				boolean matchF1 = (f1project == null || f1project.equals(listmap.get("f1project_name")));
				boolean matchF2 = (f2project == null || f2project.equals(listmap.get("f2project_name")));
				boolean matchF3 = (f3project == null || f3project.equals(listmap.get("f3project_name")));

				// 如果所有条件都满足（或者条件为空），则添加到结果列表中
				if (matchF1 && matchF2 && matchF3) {
					originalList.add(listmap);
				}

				if(inoutlevel!="0"&&inoutlevel!=null) {

					List<Map<String, Object>> levelList = new ArrayList<>();

					// 使用流来过滤level为1的对象，并将结果添加到listToCopyInto中
					// 注意：这里我们直接赋值给listToCopyInto，这意味着它之前的所有内容将被过滤后的内容替换
					// 如果你想要保留原有内容并添加新内容，应该使用addAll而不是赋值
					levelList = originalList.stream()
							.filter(map -> map.containsKey("classlevel") && ( map.get("classlevel")).equals(inoutlevel))
							.collect(Collectors.toList());
					return levelList;
				}

			}
		}

		if(inoutlevel!="0"&&inoutlevel!=null) {
			List<Map<String, Object>> levelList = new ArrayList<>();

			// 使用流来过滤level为1的对象，并将结果添加到listToCopyInto中
			// 注意：这里我们直接赋值给listToCopyInto，这意味着它之前的所有内容将被过滤后的内容替换
			// 如果你想要保留原有内容并添加新内容，应该使用addAll而不是赋值
			levelList = originalList.stream()
					.filter(map -> map.containsKey("classlevel") && ( map.get("classlevel")).equals(inoutlevel))
					.collect(Collectors.toList());
			return levelList;
		}

		return originalList;
	}

	//查询结果根据当前支出科目的父类分类
	private void initFundsource(List<Map<String, Object>> list) {
		//根据资金来源
		for(Map map : list) {
			map.put("oneup_01",new Double(0));
			map.put("onedown_01",new Double(0));
			map.put("twoup_01",new Double(0));
			map.put("twodown_01",new Double(0));
			map.put("oneup_02",new Double(0));
			map.put("onedown_02",new Double(0));
			map.put("twoup_02",new Double(0));
			map.put("twodown_02",new Double(0));
			map.put("oneup_03",new Double(0));
			map.put("onedown_03",new Double(0));
			map.put("twoup_03",new Double(0));
			map.put("twodown_03",new Double(0));
			map.put("oneup_04",new Double(0));
			map.put("onedown_04",new Double(0));
			map.put("twoup_04",new Double(0));
			map.put("twodown_04",new Double(0));
			map.put("oneup_05",new Double(0));
			map.put("onedown_05",new Double(0));
			map.put("twoup_05",new Double(0));
			map.put("twodown_05",new Double(0));
			String sourcecode= map.get("sourcecode").toString();
			map.put("oneup_"+sourcecode, map.get("amount_firstup")==null?0:map.get("amount_firstup"));
			map.put("onedown_"+sourcecode,map.get("amount_firstdown")==null?0:map.get("amount_firstdown"));
			map.put("twoup_"+sourcecode,map.get("amount_secondup")==null?0:map.get("amount_secondup"));
			map.put("twodown_"+sourcecode,map.get("amount_seconddown")==null?0:map.get("amount_seconddown"));
			//计算合计
			map.put("amount_oneup", map.get("amount_firstup")==null?0:map.get("amount_firstup"));
			map.put("amount_onedown",map.get("amount_firstdown")==null?0:map.get("amount_firstdown"));
			map.put("amount_twoup",map.get("amount_secondup")==null?0:map.get("amount_secondup"));
			map.put("amount_twodown",map.get("amount_seconddown")==null?0:map.get("amount_seconddown"));

		}


	}
	//递归查上级并计算

	private List<Map<String,Object>> initList(List<Map<String,Object>> list,List<Map<String,Object>> newlist) throws DAOException {

		//获取上级

		//根据上级分组
		Map<String, List<Map<String, Object>>> grouped = list.stream()
				.collect(Collectors.groupingBy(
						map -> map.get("inoutbusiclassparent")==null?"top":(String)map.get("inoutbusiclassparent"), // 分组键
						Collectors.toList() // 收集器，这里简单地将元素放入列表中
				));

		List getList = new ArrayList();


		for (Object key : grouped.keySet()) {
			if(!"top".equals(key)) {

				List<Map<String,Object>> groupedList =grouped.get(key);
				Map<String,Object> newMap = new HashMap<String,Object>();
				//     	 newMap = groupedList.get(0);
				//计算总值
				Double sum = 0.00;
				Double oneup_01Sum = 0.00, oneup_02Sum = 0.00, oneup_03Sum = 0.00, oneup_04Sum = 0.00, oneup_05Sum = 0.00;
				Double twoup_01Sum = 0.00, twoup_02Sum = 0.00, twoup_03Sum = 0.00, twoup_04Sum = 0.00, twoup_05Sum = 0.00;
				Double onedown_01Sum = 0.00, onedown_02Sum = 0.00, onedown_03Sum = 0.00, onedown_04Sum = 0.00, onedown_05Sum = 0.00;
				Double twodown_01Sum = 0.00, twodown_02Sum = 0.00, twodown_03Sum = 0.00, twodown_04Sum = 0.00, twodown_05Sum = 0.00;
				//获取上级编码
				String sql = "select code,pk_parent inoutbusiclassparent,name inoutbusiclassname,pk_inoutbusiclass,def1 classlevel  from bd_inoutbusiclass where pk_inoutbusiclass='"+key.toString()+"'";
				Map<String,Object> fatherMap = (Map<String,Object>)getBaseDAO().executeQuery(sql, new MapProcessor());
				for(Map map: groupedList) {

					//计算列和
					if ( map.get("oneup_01") instanceof Number) {
						oneup_01Sum += ((Number) map.get("oneup_01")).doubleValue();
					}
					if ( map.get("oneup_02") instanceof Number) {
						oneup_02Sum += ((Number) map.get("oneup_02")).doubleValue();
					}
					if ( map.get("oneup_03") instanceof Number) {
						oneup_03Sum += ((Number) map.get("oneup_03")).doubleValue();
					}
					if ( map.get("oneup_04") instanceof Number) {
						oneup_04Sum += ((Number) map.get("oneup_04")).doubleValue();
					}
					if ( map.get("oneup_05") instanceof Number) {
						oneup_05Sum += ((Number) map.get("oneup_05")).doubleValue();
					}
					if ( map.get("twoup_01") instanceof Number) {
						twoup_01Sum += ((Number) map.get("twoup_01")).doubleValue();
					}
					if ( map.get("twoup_02") instanceof Number) {
						twoup_02Sum += ((Number) map.get("twoup_02")).doubleValue();
					}
					if ( map.get("twoup_03") instanceof Number) {
						twoup_03Sum += ((Number) map.get("twoup_03")).doubleValue();
					}
					if ( map.get("twoup_04") instanceof Number) {
						twoup_04Sum += ((Number) map.get("twoup_04")).doubleValue();
					}
					if ( map.get("twoup_05") instanceof Number) {
						twoup_05Sum += ((Number) map.get("twoup_05")).doubleValue();
					}
					if ( map.get("onedown_01") instanceof Number) {
						onedown_01Sum += ((Number) map.get("onedown_01")).doubleValue();
					}
					if ( map.get("onedown_02") instanceof Number) {
						onedown_02Sum += ((Number) map.get("onedown_02")).doubleValue();
					}
					if ( map.get("onedown_03") instanceof Number) {
						onedown_03Sum += ((Number) map.get("onedown_03")).doubleValue();
					}
					if ( map.get("onedown_04") instanceof Number) {
						onedown_04Sum += ((Number) map.get("onedown_04")).doubleValue();
					}
					if ( map.get("onedown_05") instanceof Number) {
						onedown_05Sum += ((Number) map.get("onedown_05")).doubleValue();
					}
					if ( map.get("twodown_01") instanceof Number) {
						twodown_01Sum += ((Number) map.get("twodown_01")).doubleValue();
					}
					if ( map.get("twodown_02") instanceof Number) {
						twodown_02Sum += ((Number) map.get("twodown_02")).doubleValue();
					}
					if ( map.get("twodown_03") instanceof Number) {
						twodown_03Sum += ((Number) map.get("twodown_03")).doubleValue();
					}
					if ( map.get("twodown_04") instanceof Number) {
						twodown_04Sum += ((Number) map.get("twodown_04")).doubleValue();
					}
					if ( map.get("twodown_05") instanceof Number) {
						twodown_05Sum += ((Number) map.get("twodown_05")).doubleValue();
					}


				}
				newMap.put("oneup_01",oneup_01Sum);
				newMap.put("onedown_01",onedown_01Sum);
				newMap.put("twoup_01",twoup_01Sum);
				newMap.put("twodown_01",twodown_01Sum);
				newMap.put("oneup_02",oneup_02Sum);
				newMap.put("onedown_02",onedown_02Sum);
				newMap.put("twoup_02",twoup_02Sum);
				newMap.put("twodown_02",twodown_02Sum);
				newMap.put("oneup_03",oneup_03Sum);
				newMap.put("onedown_03",onedown_03Sum);
				newMap.put("twoup_03",twoup_03Sum);
				newMap.put("twodown_03",twodown_03Sum);
				newMap.put("oneup_04",oneup_04Sum);
				newMap.put("onedown_04",onedown_04Sum);
				newMap.put("twoup_04",twoup_04Sum);
				newMap.put("twodown_04",twodown_04Sum);
				newMap.put("oneup_05",oneup_05Sum);
				newMap.put("onedown_05",onedown_05Sum);
				newMap.put("twoup_05",twoup_05Sum);
				newMap.put("twodown_05",twodown_05Sum);
				if(fatherMap!=null) {
					newMap.put("inoutbusiclassname",fatherMap.get("inoutbusiclassname"));
					newMap.put("inoutbusiclasscode",fatherMap.get("code"));
					newMap.put("inoutbusiclassparent",fatherMap.get("inoutbusiclassparent"));
					newMap.put("pk_inoutclass",fatherMap.get("pk_inoutbusiclass"));
					newMap.put("classlevel",fatherMap.get("classlevel"));
				}
				//计算合计
				newMap.put("amount_oneup",oneup_01Sum+oneup_02Sum+oneup_03Sum+oneup_04Sum+oneup_05Sum);
				newMap.put("amount_onedown",onedown_01Sum+onedown_02Sum+onedown_03Sum+onedown_04Sum+onedown_05Sum);
				newMap.put("amount_twoup",twoup_01Sum+twoup_02Sum+twoup_03Sum+twoup_04Sum+twoup_05Sum);
				newMap.put("amount_twodown",twodown_01Sum+twodown_02Sum+twodown_03Sum+twodown_04Sum+twodown_05Sum);

				//  list.add(newMap);

				newlist.add(newMap);
				getList.add(newMap);
			}
		}

		list.addAll(getList);

		if(!getList.isEmpty()) {
			initList(getList,newlist);

		}

		return newlist;

	}



	public static void assignLevels(List<Map<String, Object>> list) {
		// 创建一个Map来存储已经计算过级别的条目的级别
		Map<Object, Integer> levelMap = new HashMap<>();

		// 初始化时，假设所有顶级条目的父级ID为null或空字符串，级别为1
		for (Map<String, Object> map : list) {
			Object parentId = map.get("inoutbusiclassparent");
			if (parentId == null || parentId.toString().isEmpty()) {
				map.put("level", 1);
				levelMap.put(map.get("pk_inoutclass"), 1);
			}
		}

		// 使用队列进行广度优先搜索（BFS），计算非顶级条目的级别
		Queue<Map<String, Object>> queue = new LinkedList<>();
		// 将所有顶级条目加入队列
		for (Map<String, Object> map : list) {
			if (map.containsKey("level")) { // 只加入已经确定为顶级的条目
				queue.offer(map);
			}
		}

		while (!queue.isEmpty()) {
			Map<String, Object> current = queue.poll();
			Object currentId = current.get("pk_inoutclass");
			int currentLevel = levelMap.get(currentId);

			// 遍历当前条目的所有子条目（这里假设是单向关系，实际上需要额外的数据结构或逻辑来维护）
			// 但在这个例子中，我们直接在原list中查找
			for (Map<String, Object> child : list) {
				Object childParentId = child.get("inoutbusiclassparent");
				if (childParentId != null && childParentId.equals(currentId)) {
					// 如果找到子条目，计算其级别并加入队列
					int childLevel = currentLevel + 1;
					child.put("level", childLevel);
					levelMap.put(child.get("pk_inoutclass"), childLevel);
					queue.offer(child);
				}
			}


		}
	}

	private List<Map<String,Object>> initnewList(List<Map<String,Object>> list){
		List<Map<String, Object>> returnList =  new ArrayList();
		Map<String, List<Map<String, Object>>> grouped = list.stream()
				.collect(Collectors.groupingBy(
						map -> map.get("pk_inoutclass").toString(), // 分组键
						Collectors.toList() // 收集器，这里简单地将元素放入列表中
				));
		for (Object key : grouped.keySet()) {

			List<Map<String, Object>> groupedList= grouped.get(key);
			//key相同的项进行合并
			Double sum = 0.00;
			Double oneup_01Sum = 0.00, oneup_02Sum = 0.00, oneup_03Sum = 0.00, oneup_04Sum = 0.00, oneup_05Sum = 0.00;
			Double twoup_01Sum = 0.00, twoup_02Sum = 0.00, twoup_03Sum = 0.00, twoup_04Sum = 0.00, twoup_05Sum = 0.00;
			Double onedown_01Sum = 0.00, onedown_02Sum = 0.00, onedown_03Sum = 0.00, onedown_04Sum = 0.00, onedown_05Sum = 0.00;
			Double twodown_01Sum = 0.00, twodown_02Sum = 0.00, twodown_03Sum = 0.00, twodown_04Sum = 0.00, twodown_05Sum = 0.00;

			for(Map map:groupedList) {
				//计算列和
				if ( map.get("oneup_01") instanceof Number) {
					oneup_01Sum += ((Number) map.get("oneup_01")).doubleValue();
				}
				if ( map.get("oneup_02") instanceof Number) {
					oneup_02Sum += ((Number) map.get("oneup_02")).doubleValue();
				}
				if ( map.get("oneup_03") instanceof Number) {
					oneup_03Sum += ((Number) map.get("oneup_03")).doubleValue();
				}
				if ( map.get("oneup_04") instanceof Number) {
					oneup_04Sum += ((Number) map.get("oneup_04")).doubleValue();
				}
				if ( map.get("oneup_05") instanceof Number) {
					oneup_05Sum += ((Number) map.get("oneup_05")).doubleValue();
				}
				if ( map.get("twoup_01") instanceof Number) {
					twoup_01Sum += ((Number) map.get("twoup_01")).doubleValue();
				}
				if ( map.get("twoup_02") instanceof Number) {
					twoup_02Sum += ((Number) map.get("twoup_02")).doubleValue();
				}
				if ( map.get("twoup_03") instanceof Number) {
					twoup_03Sum += ((Number) map.get("twoup_03")).doubleValue();
				}
				if ( map.get("twoup_04") instanceof Number) {
					twoup_04Sum += ((Number) map.get("twoup_04")).doubleValue();
				}
				if ( map.get("twoup_05") instanceof Number) {
					twoup_05Sum += ((Number) map.get("twoup_05")).doubleValue();
				}
				if ( map.get("onedown_01") instanceof Number) {
					onedown_01Sum += ((Number) map.get("onedown_01")).doubleValue();
				}
				if ( map.get("onedown_02") instanceof Number) {
					onedown_02Sum += ((Number) map.get("onedown_02")).doubleValue();
				}
				if ( map.get("onedown_03") instanceof Number) {
					onedown_03Sum += ((Number) map.get("onedown_03")).doubleValue();
				}
				if ( map.get("onedown_04") instanceof Number) {
					onedown_04Sum += ((Number) map.get("onedown_04")).doubleValue();
				}
				if ( map.get("onedown_05") instanceof Number) {
					onedown_05Sum += ((Number) map.get("onedown_05")).doubleValue();
				}
				if ( map.get("twodown_01") instanceof Number) {
					twodown_01Sum += ((Number) map.get("twodown_01")).doubleValue();
				}
				if ( map.get("twodown_02") instanceof Number) {
					twodown_02Sum += ((Number) map.get("twodown_02")).doubleValue();
				}
				if ( map.get("twodown_03") instanceof Number) {
					twodown_03Sum += ((Number) map.get("twodown_03")).doubleValue();
				}
				if ( map.get("twodown_04") instanceof Number) {
					twodown_04Sum += ((Number) map.get("twodown_04")).doubleValue();
				}
				if ( map.get("twodown_05") instanceof Number) {
					twodown_05Sum += ((Number) map.get("twodown_05")).doubleValue();
				}


			}
			Map<String,Object> newMap = new HashMap();
			newMap.put("oneup_01",oneup_01Sum);
			newMap.put("onedown_01",onedown_01Sum);
			newMap.put("twoup_01",twoup_01Sum);
			newMap.put("twodown_01",twodown_01Sum);
			newMap.put("oneup_02",oneup_02Sum);
			newMap.put("onedown_02",onedown_02Sum);
			newMap.put("twoup_02",twoup_02Sum);
			newMap.put("twodown_02",twodown_02Sum);
			newMap.put("oneup_03",oneup_03Sum);
			newMap.put("onedown_03",onedown_03Sum);
			newMap.put("twoup_03",twoup_03Sum);
			newMap.put("twodown_03",twodown_03Sum);
			newMap.put("oneup_04",oneup_04Sum);
			newMap.put("onedown_04",onedown_04Sum);
			newMap.put("twoup_04",twoup_04Sum);
			newMap.put("twodown_04",twodown_04Sum);
			newMap.put("oneup_05",oneup_05Sum);
			newMap.put("onedown_05",onedown_05Sum);
			newMap.put("twoup_05",twoup_05Sum);
			newMap.put("twodown_05",twodown_05Sum);

			newMap.put("inoutbusiclassname",groupedList.get(0).get("inoutbusiclassname"));
			newMap.put("inoutbusiclasscode",groupedList.get(0).get("inoutbusiclasscode"));
			newMap.put("inoutbusiclassparent",groupedList.get(0).get("inoutbusiclassparent"));
			newMap.put("pk_inoutclass",groupedList.get(0).get("pk_inoutbusiclass"));
			newMap.put("classlevel",groupedList.get(0).get("classlevel"));

			//计算合计
			newMap.put("amount_oneup",oneup_01Sum+oneup_02Sum+oneup_03Sum+oneup_04Sum+oneup_05Sum);
			newMap.put("amount_onedown",onedown_01Sum+onedown_02Sum+onedown_03Sum+onedown_04Sum+onedown_05Sum);
			newMap.put("amount_twoup",twoup_01Sum+twoup_02Sum+twoup_03Sum+twoup_04Sum+twoup_05Sum);
			newMap.put("amount_twodown",twodown_01Sum+twodown_02Sum+twodown_03Sum+twodown_04Sum+twodown_05Sum);

			returnList.add(newMap);
			//  list.add(newMap);







		}




		return returnList;

	}

	private String getpkbudgetdept(String pk_budgetdept) throws BusinessException {

		String userId = InvocationInfoProxy.getInstance().getUserId(); // 操作员主键
		String sql = "SELECT hrpbm_budgetdept.code code, hrpbm_budgetdept.pk_budgetdept pk_budgetdept, bd_psnjob.ismainjob ismainjob\n" +
				"  FROM hrpbm_budgetdept \n" +
				"  LEFT JOIN bd_psnjob ON hrpbm_budgetdept.pk_dept = bd_psnjob.pk_dept \n" +
				"  LEFT JOIN sm_user ON bd_psnjob.psncode = sm_user.user_code \n" +
				" WHERE NVL(hrpbm_budgetdept.dr, 0) = 0 \n" +
				"   AND NVL(bd_psnjob.dr, 0) = 0 \n" +
				"   AND NVL(sm_user.dr, 0) = 0 \n" +
				"   AND NVL(sm_user.dr, 0) = 0 \n" +
				"   AND NVL(sm_user.dr, 0) = 0 \n" +
				"   AND sm_user.cuserid = '" + userId + "' \n";// 当前用户主键
		// 还需过滤往期任职任职记录
		List<Map<String, Object>> sqlResult = (List<Map<String, Object>>) this.getBaseDAO().executeQuery(sql,
				new MapListProcessor());

		// 预算部门为空, 查看是否财务部,财务部才能查所有或者 只能看自己对应部门的数据
		for (int i = 0; sqlResult != null && i < sqlResult.size(); i++) {
			if (cwbudgetdeptcode.equals(sqlResult.get(i).get("code")) || (StringUtils.isNotBlank(pk_budgetdept)
					&& pk_budgetdept.equals(sqlResult.get(i).get("pk_budgetdept")))) {
				if(pk_budgetdept == null){
					return "'"+sqlResult.get(i).get("pk_budgetdept").toString()+"'";
				}
				return java.util.Arrays.stream(pk_budgetdept.split(",")) .map(s -> "'" + s + "'").collect(Collectors.joining(","));
			}
		}
		if(StringUtils.isBlank(pk_budgetdept)) {
			if(!sqlResult.isEmpty()) {
				return (String) sqlResult.get(0).get("pk_budgetdept");
			}
		}
		return null; // 当前账号无关联部门
	}
	public static MetaData getMetaData(String[] fieldTypes, String[] fields) {
		if (ArrayUtils.isEmpty(fieldTypes) || ArrayUtils.isEmpty(fields)) {
			ExceptionUtils.wrappBusinessException("报表字段列或字段类型不能为空，请检查！！！");
		}
		// 设置元数据字段的类型和精度
		List<Field> fieldList = new ArrayList<Field>();
		for (int i = 0; i < fieldTypes.length; i++) {
			String javatype = fieldTypes[i];
			Field field = new Field();
			// 用于给报表元数据设置字段名称
			field.setFldname(fields[i]);
			if ("String".equals(javatype)) {
				field.setDbColumnType(Types.VARCHAR);
				// 设置字符串的长度
				field.setPrecision(200);
			} else if ("Double".equals(javatype)) {

//				field.setDbColumnType(Types.VARCHAR);
//				// 设置字符串的长度
//				field.setPrecision(200);
				field.setDbColumnType(Types.DECIMAL);
				field.setPrecision(20);
				field.setScale(2);
			} else if ("Integer".equals(javatype)) {
				field.setDbColumnType(Types.INTEGER);
			} else if ("UFDate".equals(javatype)) {
				field.setDbColumnType(Types.CHAR);
				field.setPrecision(19);
			} else if ("UFBoolean".equals(javatype)) {
				field.setDbColumnType(Types.BOOLEAN);
			}
			fieldList.add(field);
		}
		return new MetaData(fieldList.toArray(new Field[fieldList.size()]));
	}

	public static DataSet buildDataSetobj(MetaData meta, List<Map> list, String[] fields) {
		if (ArrayUtils.isEmpty(fields)) {
			ExceptionUtils.wrappBusinessException("报表字段列不能为空，请检查！！！");
		}
		DataSet ds = null;
		if (null == list || list.size() == 0) {
			// 返回空数据集, 用于给语义模型加载空数据用
			Object[][] datas = new Object[1][fields.length];
			ds = new DataSet(meta, datas);
		} else {
			Object[][] datas = new Object[list.size()][fields.length];
			for(int i = 0;i < list.size();i++){
				for(int j = 0; j < fields.length; j++ ) {
					datas[i][j] = list.get(i).get(fields[j]);
					//vos[i].getAttributeValue(fields[j]);
				}
			}
			ds = new DataSet(meta, datas);
		}
		return ds;
	}
}
